package epimarket.helper;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.lang.reflect.*;

public class DBRequest<T extends Object> {
	private DBConnect db;
	private T model;
	
	public DBRequest(DBConnect connexion, T obj) {
		this.db = connexion;
		this.model = obj;
	}
	
	public int request(String q) {
		int statut = -1;
		try {
		    Statement statement = this.db.getConnexion().createStatement();
		    statut = statement.executeUpdate(q);
		} catch ( SQLException e ) {
		}
		return statut;
	}
	
	public int request_id(String q) {
		int statut = -1;
		try {
		    Statement statement = this.db.getConnexion().createStatement();
		    statut = statement.executeUpdate(q, Statement.RETURN_GENERATED_KEYS);
		    ResultSet resultat = statement.getGeneratedKeys();
	    	if (resultat.next()) {
	    		return resultat.getInt(1);
	    	}
		} catch ( SQLException e ) {
		}
		return statut;
	}

    @SuppressWarnings({"unchecked", "rawtypes"})
	public T find(int id) {
		try {
			DBQuery dbq = new DBQuery<T>();
			String nameclass = this.model.getClass().getSimpleName().substring(0, 1).toUpperCase() + this.model.getClass().getSimpleName().substring(1).toLowerCase();
			Class<?> cl = Class.forName(nameclass);
			Statement statement = this.db.getConnexion().createStatement();
			ResultSet resultat = statement.executeQuery(dbq.find(this.model, id));
			ResultSetMetaData meta = resultat.getMetaData();
			if (resultat.next()) {
				T obj = (T)cl.newInstance();
				for (int i = 1; i <= meta.getColumnCount(); i++){
					Field field = cl.getDeclaredField(meta.getColumnName(i));
					field.setAccessible(true);
					field.set(obj, resultat.getObject(i));
				}
				return obj;
			}
		} catch (Exception e ) {
		}
		return null;
	}

    @SuppressWarnings("unchecked")
	public ArrayList<T> all() {
		ArrayList<T> list = new ArrayList<T>();
		String nameclass = "";
		
		try {
			DBQuery<T> dbq = new DBQuery<T>();
			nameclass = "epimarket.beans." + this.model.getClass().getSimpleName().substring(0, 1).toUpperCase() + this.model.getClass().getSimpleName().substring(1).toLowerCase();
			Class<?> cl = Class.forName(nameclass);
			Statement statement = this.db.getConnexion().createStatement();
			ResultSet resultat = statement.executeQuery(dbq.all(this.model));
			ResultSetMetaData meta = resultat.getMetaData();
			while (resultat.next()) {
				T obj = (T)cl.newInstance();
				for (int i = 1; i <= meta.getColumnCount(); i++){
					Field field = cl.getDeclaredField(meta.getColumnName(i));
					field.setAccessible(true);
					field.set(obj, resultat.getObject(i));
				}
				list.add(obj);
			}
		} catch (Exception e) {
		}
		return list;
	}
    
    @SuppressWarnings("unchecked")
	public ArrayList<T> select(String query) {
		ArrayList<T> list = new ArrayList<T>();
		String nameclass = "";
		
		try {
			nameclass = "epimarket.beans." + this.model.getClass().getSimpleName().substring(0, 1).toUpperCase() + this.model.getClass().getSimpleName().substring(1).toLowerCase();
			Class<?> cl = Class.forName(nameclass);
			Statement statement = this.db.getConnexion().createStatement();
			ResultSet resultat = statement.executeQuery(query);
			ResultSetMetaData meta = resultat.getMetaData();
			while (resultat.next()) {
				T obj = (T)cl.newInstance();
				for (int i = 1; i <= meta.getColumnCount(); i++){
					Field field = cl.getDeclaredField(meta.getColumnName(i));
					field.setAccessible(true);
					field.set(obj, resultat.getObject(i));
				}
				list.add(obj);
			}
		} catch (Exception e) {
		}
		return list;
	}
}
